<?php

header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Thu, 1 Jan 1970 01:00:00 GMT"); // Date in the past
header('Content-type: text/plain');
error_reporting(E_ERROR | E_PARSE | E_CORE_ERROR);
ini_set('log_errors', '1');
ini_set('error_log', 'php_error.log');

//ini_set('display_errors','1');

$passcode = '7cab1de0f7d3e5a0d5559d4fb360f3f6'; // n2 standard
$docroot = $_ENV['DOCUMENT_ROOT'];
$mirrorroot = $docroot . '/mirror';

function webPath($path, $file) {
	// Returns full file path sans ending slash /
	// /path = webroot relative path/file
	// :/path = file system full path/file
	// @/path = mirror relative path/file
	// all else = path/file
	// $path and/or $file can be empty or respectivly full path
	global $docroot, $mirrorroot;
	if ($path && substr($path, -1, 1) != '/')
		$path .= '/';
	$path = ($path ? $path : '') . ($file ? $file : '');
	if (substr($path, 0, 1) == '/')
		$path = $docroot . $path;
	if (substr($path, 0, 2) == ':/')
		$path = substr($path, 1);
	if (substr($path, 0, 2) == '@/')
		$path = $mirrorroot . substr($path, 1);
	if ($path && substr($path, -1, 1) == '/')
		$path = substr($path, 0, strlen($path) - 1);
	return $path;
}

function req($nm, $default) {
	$v = $_POST[$nm];
	if ($v == 'TRUE' || $v == 'true')
		return TRUE;
	if ($v == 'FALSE' || $v == 'false')
		return FALSE;
	if ($v) {
		if (0 === strpos($v, 'transfer/double-encoded:'))
			return pureTx(rawurldecode(substr($v, 24)));
		return pureTx($v);
	}
	$v = $_GET[$nm];
	if ($v == 'TRUE' || $v == 'true')
		return TRUE;
	if ($v == 'FALSE' || $v == 'false')
		return FALSE;
	if ($v)
		return pureTx($v);
	return $default;
}

function pureTx($tx) {
	if (get_magic_quotes_gpc() == 0)
		return $tx;
	return stripslashes($tx);
}

$password = req('password', '');
$path = req('path', '');
$recur = req('recur', 'false');
$key = req('key', 'none');
$hidden = req('hidden');
$callbackName = req('callback');

$ot = '';
$totdirs = 0;
$totfiles = 0;
$totsize = 0;
$exists = FALSE;

$path = webPath($path);

if (!$passcode || md5($password) !== $passcode) {
	$ot .= "[\n";
	$ot .= Nvp("result", "false");
	$ot .= NvpEnd();
	$ot .= "]";
	if ($callback)
		echo "$callback($ot);";
	else
		echo $ot;
	exit(0);
}

function Nvp($name, $value)
{
	return "{\"Key\":\"$name\",\"Value\":$value},\n";
}

function NvpEnd()
{
	return "{\"Key\":\"end\",\"Value\":true}\n";
}

function TreeList($dirpath, $recur) {
	global $totdirs, $totfiles, $totsize, $path, $exists, $key;
	$ot = '';
	$level = 1;

	// Trim trailing slash
	$ln = strlen($dirpath);
	if ($ln > 0)
		$en = substr($dirpath, $ln - 1, 1); // the character at the end of the path
	else
		$en = '';
	if ($en == '/' || $en == "\\")
		$dirpath = substr($dirpath, 0, $ln - 1);

	//$ot .= "this.dirpath = '../$dirpath';\n";

	function getDirFiles($dirpath, $pre, $level, $recur) {
		//
		// Get folder and file lists
		//
		global $totdirs, $totfiles, $totsize, $exists, $hidden;
		$level++;
		$ot = '';
		$numdirs = 0;
		$numfiles = 0;
		$exists = TRUE;
		if (!$dirpath)
			$dirpath = '.';
		$handle = opendir($dirpath);
		if ($handle) {
			$exists = TRUE;
			while (FALSE !== ($file = readdir($handle))) {
				$nm = $dirpath . '/' . $file;
				if (is_dir($nm)) {
					if ($file != '.' && $file != '..') {
						$dirarr[$numdirs] = $file;
						$numdirs++;
					}
				} else {
					if (!is_link($nm) && ($hidden == 'true' || substr($file, 0, 1) != '.')) {
						$filearr[] = $file;
						$numfiles++;
					}
				}
			}
			closedir($handle);
		}

		if ($numdirs > 1)
			sort($dirarr);
		if ($numfiles > 1)
			sort($filearr);

		// Collect file sizes and modification times
		if ($numfiles > 0)
			for ($i = 0; $i < $numfiles; $i++) {
				$nm = $dirpath . '/' . $filearr[$i];
				$sizearr[] = filesize($nm);
				$dts = strftime("%Y-%m-%d %H:%M:%S", filemtime($nm)) . " UTC";
				$timearr[] = strtotime($dts);
				//$timearr[] = gmdate('U', filemtime($nm));
				//$timearr[] = filemtime($nm);
				$uimearr[] = gmdate('"Y-m-d H:i:s",', filemtime($nm));
			}

		if ($numdirs > 0)
			for ($i = 0; $i < $numdirs; $i++) {
				$nm = $pre . $dirarr[$i];
				$ot .= "[";
				$ot .= json_encode($nm) . ",";
				$ot .= "0,";
				$ot .= "0,";
				$ot .= 'true,'; // is folder
				$ot .= $level;
				$ot .= "],\n";
			}
		if ($numfiles > 0)
			for ($i = 0; $i < $numfiles; $i++) {
				$nm = $pre . $filearr[$i];
				$ot .= "[";
				$ot .= json_encode($nm) . ",";
				$ot .= $sizearr[$i] . ",";
				$ot .= $timearr[$i] . ",";
				$ot .= 'false,'; // is not folder
				$ot .= json_encode($uimearr[$i]);
				//$ot .= $level;
				$ot .= "],\n";
				$totsize += $sizearr[$i];
			}
		$totdirs += $numdirs;
		$totfiles += $numfiles;

		if ($recur == 'true')
			for ($i = 0; $i < $numdirs; $i++) {
				$ot .= getDirFiles($dirpath . '/' . $dirarr[$i], $pre . $dirarr[$i] . '/', $level, $recur);
			}
		return $ot;
	}

	if (file_exists($dirpath))
		$list = trim(getDirFiles("$dirpath", "", 0, $recur), ",\n");

	$ot .= "[\n";
	$ot .= Nvp("result", "true");
	$ot .= Nvp("tree", gettimeofday(true));
	$ot .= Nvp("path", json_encode($path));
	$ot .= Nvp("cwd", json_encode(getcwd()));
	$ot .= Nvp("folders", json_encode($totdirs));
	$ot .= Nvp("files", $totfiles);
	$ot .= Nvp("size", $totsize);
	$ot .= Nvp("exists", ($exists ? 'true' : 'false'));
	$ot .= Nvp("key", json_encode($key));
	$ot .= Nvp("list", "[\n$list\n]");
	$ot .= NvpEnd();
	$ot .= "]";

	return $ot;
}

$ot = TreeList($path, $recur);
if ($callback)
	echo "$callback($ot);";
else
	echo $ot;
?>